package main

import (
	"github.com/xgdapg/wtk"
	"math"
	"strconv"
	"strings"
	"time"
)

type AdminHandler struct {
	wtk.Handler
}

func (this *AdminHandler) IsLogin() bool {
	return this.Session.Get("IsLogin") == "1"
}

type AdminLoginHandler struct {
	AdminHandler
}

func (this *AdminLoginHandler) Get() {
	if this.IsLogin() {
		this.Context.RedirectUrl("/admin/index")
		return
	}

	this.Template.SetTemplateFile(cfg.AdminTplPath() + "/login.tpl")
}

func (this *AdminLoginHandler) Post() {
	pwd := this.Context.GetFormVar("password")
	//check password
	if getHash(pwd, cfg.PwdSecret) != cfg.Password {
		this.Template.SetVar("ErrMsg", "密码验证未通过")
		this.Template.SetTemplateFile(cfg.AdminTplPath() + "/login.tpl")
		return
	}

	this.Session.Set("IsLogin", "1")
	this.Context.RedirectUrl("/admin/index")
}

type AdminLogoutHandler struct {
	AdminHandler
}

func (this *AdminLogoutHandler) Get() {
	if this.IsLogin() {
		this.Session.Delete("IsLogin")
	}
	this.Context.RedirectUrl("/admin/index")
}

type AdminIndexHandler struct {
	AdminHandler
}

func (this *AdminIndexHandler) Get() {
	if !this.IsLogin() {
		this.Context.RedirectUrl("/admin/login")
		return
	}

	//
	this.Context.RedirectUrl("/admin/posts")
	return

	this.Template.SetTemplateFile(cfg.AdminTplPath() + "/wrap.tpl")
	this.Template.SetSubTemplateFile("content", cfg.AdminTplPath()+"/index.tpl")
}

type AdminPostsHandler struct {
	AdminHandler
}

func (this *AdminPostsHandler) Get() {
	if !this.IsLogin() {
		this.Context.RedirectUrl("/admin/login")
		return
	}

	page := 1
	strPage := this.Context.GetPathVar("Page")
	if strPage != "" {
		page, _ = strconv.Atoi(strPage)
	}

	tag := this.Context.GetPathVar("TagName")

	var list []*PostData
	var err error
	var totalCnt int

	if tag == "" {
		list, err = model.GetPosts(page)
	} else {
		list, err = model.GetPostsByTag(tag, page)
	}
	if err != nil {
		this.Context.Abort(500, "")
		return
	}

	if tag == "" {
		totalCnt, err = model.GetPostsCnt()
	} else {
		totalCnt, err = model.GetPostsCntByTag(tag)
	}
	if err != nil {
		this.Context.Abort(500, "")
		return
	}

	maxPage := int(math.Ceil(float64(totalCnt) / float64(cfg.NumPerPage)))
	prev := page - 1
	next := page + 1
	if next > maxPage {
		next = 0
	}

	this.Template.SetVar("PostList", list)
	this.Template.SetVar("CurrPage", page)
	this.Template.SetVar("PrevPage", prev)
	this.Template.SetVar("NextPage", next)
	this.Template.SetVar("MaxPage", maxPage)
	if tag == "" {
		this.Template.SetVar("PageUrl", "/admin/posts/")
	} else {
		this.Template.SetVar("PageUrl", "/admin/posts/tag/"+tag+"/")
	}
	this.Template.SetTemplateFile(cfg.AdminTplPath() + "/wrap.tpl")
	this.Template.SetSubTemplateFile("content", cfg.AdminTplPath()+"/posts.tpl")
}

type AdminPostHandler struct {
	AdminHandler
}

func (this *AdminPostHandler) Get() {
	if !this.IsLogin() {
		this.Context.RedirectUrl("/admin/login")
		return
	}

	postId := 0
	strPostId := this.Context.GetPathVar("PostId")
	if strPostId != "" {
		postId, _ = strconv.Atoi(strPostId)
	}

	data := &PostData{Tags: []string{}}

	if postId > 0 {
		var err error
		data, err = model.GetPostById(postId)
		if err != nil {
			this.Context.Abort(500, "")
			return
		}
	}

	allTags, err := model.GetAllTags()
	if err != nil {
		this.Context.Abort(500, "")
		return
	}

	this.Template.SetVar("Post", data)
	this.Template.SetVar("PostTags", strings.Join(data.Tags, ","))
	this.Template.SetVar("AllTags", allTags)
	this.Template.SetTemplateFile(cfg.AdminTplPath() + "/wrap.tpl")
	this.Template.SetSubTemplateFile("content", cfg.AdminTplPath()+"/post.tpl")
}

func (this *AdminPostHandler) Post() {
	if !this.IsLogin() {
		this.Context.RedirectUrl("/admin/login")
		return
	}

	postId := 0
	strPostId := this.Context.GetPathVar("PostId")
	if strPostId != "" {
		postId, _ = strconv.Atoi(strPostId)
	}

	data := &PostData{
		Pid:      postId,
		Title:    this.Context.GetFormVar("Title"),
		Content:  this.Context.GetFormVar("Content"),
		Created:  0,
		Modified: 0,
	}
	tags := strings.Split(this.Context.GetFormVar("Tags"), ",")
	for i, tag := range tags {
		tags[i] = strings.TrimSpace(tag)
	}
	data.Tags = tags

	if postId == 0 {
		data.Created = time.Now().Unix()
	} else {
		data.Modified = time.Now().Unix()
	}

	err := model.SavePost(data)
	if err != nil {
		this.Context.Abort(500, "")
		return
	}
	this.Context.RedirectUrl("/admin/posts")
}

type AdminConfigHandler struct {
	AdminHandler
}

func (this *AdminConfigHandler) Get() {
	if !this.IsLogin() {
		this.Context.RedirectUrl("/admin/login")
		return
	}

	data, err := model.GetAllConfig()
	if err != nil {
		this.Context.Abort(500, "")
		return
	}

	this.Template.SetVar("Config", data)
	this.Template.SetTemplateFile(cfg.AdminTplPath() + "/wrap.tpl")
	this.Template.SetSubTemplateFile("content", cfg.AdminTplPath()+"/config.tpl")
}

func (this *AdminConfigHandler) Post() {
	if !this.IsLogin() {
		this.Context.RedirectUrl("/admin/login")
		return
	}

	data, err := model.GetAllConfig()
	if err != nil {
		this.Context.Abort(500, "")
		return
	}

	for _, cfgKey := range []string{"BlogName", "BlogDesc", "DomainPath", "PrefixPath", "Theme", "NumPerPage"} {
		if val := this.Context.GetFormVar(cfgKey); val != "" {
			if oval, ok := data[cfgKey]; ok && oval != val {
				if cfgKey == "NumPerPage" {
					if npp, err := strconv.Atoi(val); err != nil || npp < +0 {
						continue
					}
				}
				model.SetConfig(cfgKey, val)
			}
		}
	}
	if val := this.Context.GetFormVar("Password"); val != "" {
		val = getHash(val, data["PwdSecret"])
		model.SetConfig("Password", val)
	}

	LoadSysConfig()

	this.Context.RedirectUrl("/admin/config")
}

type AdminPluginsHandler struct {
	AdminHandler
}

func (this *AdminPluginsHandler) Get() {
	if !this.IsLogin() {
		this.Context.RedirectUrl("/admin/login")
		return
	}

	list, err := model.GetAllPlugins()
	if err != nil {
		this.Context.Abort(500, "")
		return
	}

	this.Template.SetVar("PluginList", list)
	this.Template.SetTemplateFile(cfg.AdminTplPath() + "/wrap.tpl")
	this.Template.SetSubTemplateFile("content", cfg.AdminTplPath()+"/plugins.tpl")
}

type AdminPluginHandler struct {
	AdminHandler
}

func (this *AdminPluginHandler) Get() {
	if !this.IsLogin() {
		this.Context.RedirectUrl("/admin/login")
		return
	}

	name := this.Context.GetPathVar("PluginName")

	data, err := model.GetPluginByName(name)
	if err != nil {
		this.Context.Abort(500, "")
		return
	}

	this.Template.SetVar("Plugin", data)
	this.Template.SetTemplateFile(cfg.AdminTplPath() + "/wrap.tpl")
	this.Template.SetSubTemplateFile("content", cfg.AdminTplPath()+"/plugin.tpl")
}

func (this *AdminPluginHandler) Post() {
	if !this.IsLogin() {
		this.Context.RedirectUrl("/admin/login")
		return
	}

	name := this.Context.GetPathVar("PluginName")

	enabled := false
	if this.Context.GetFormVar("Enabled") == "true" {
		enabled = true
	}
	data := this.Context.GetFormVar("Data")

	plugin := &PluginData{
		Name:    name,
		Enabled: enabled,
		Data:    data,
	}
	model.SavePlugin(plugin)

	if p, ok := pluginManager.plugins[name]; ok {
		p.Stop()
		p.SetData(data)
		if enabled {
			go p.Start()
		}
	}

	this.Context.RedirectUrl("/admin/plugins")
}

type AdminTagsHandler struct {
	AdminHandler
}

func (this *AdminTagsHandler) Get() {
	if !this.IsLogin() {
		this.Context.RedirectUrl("/admin/login")
		return
	}

	list, err := model.GetAllTags()
	if err != nil {
		this.Context.Abort(500, "")
		return
	}

	this.Template.SetVar("TagList", list)
	this.Template.SetTemplateFile(cfg.AdminTplPath() + "/wrap.tpl")
	this.Template.SetSubTemplateFile("content", cfg.AdminTplPath()+"/tags.tpl")
}

type AdminTagHandler struct {
	AdminHandler
}

func (this *AdminTagHandler) Get() {
	if !this.IsLogin() {
		this.Context.RedirectUrl("/admin/login")
		return
	}

	this.Template.SetVar("TagName", this.Context.GetPathVar("TagName"))
	this.Template.SetTemplateFile(cfg.AdminTplPath() + "/wrap.tpl")
	this.Template.SetSubTemplateFile("content", cfg.AdminTplPath()+"/tag.tpl")
}

func (this *AdminTagHandler) Post() {
	if !this.IsLogin() {
		this.Context.RedirectUrl("/admin/login")
		return
	}

	name := this.Context.GetPathVar("TagName")

	newName := strings.TrimSpace(this.Context.GetFormVar("Name"))
	if newName == "" || name == newName {
		this.Context.RedirectUrl("/admin/tags")
		return
	}

	model.SetTag(name, newName)

	this.Context.RedirectUrl("/admin/tags")
}
